<template>
  <div class="analysis-data-statistics">
    <!-- 网络算法 header -->
    <div class="data-statistics-header">
      <span>网络-算法</span>
      <a-icon
        :type="netAlgorithmFoldClose ? 'up' : 'down'"
        @click="netAlgorithmFoldClose = !netAlgorithmFoldClose"
      />
    </div>
    <!-- 网络算法 content -->
    <div
      class="data-analysis-content"
      :class="{ 'close-fold': netAlgorithmFoldClose }"
    >
      <div
        v-for="item in netAlgrithm"
        :key="item.index"
        class="data-analysis-items"
      >
        <div class="data-analysis-items-title">{{ item.name }}</div>
        <div class="data-analysis-items-info">
          <a-button
            size="small"
            class="run-button"
            @click="runFunction(item.index)"
            >运行
          </a-button>
          <div class="hover-icon">
            <a-icon-font
              v-show="isAvailable(item.index) && item.attributeName"
              :type="
                isHasMetricTag(item.metricTag) ? 'iconjianshao' : 'iconzengjia'
              "
              class="icon"
              @click="activeAttribute(item)"
            />
            <a-tooltip
              v-show="item.reportIcon && isAvailable(item.index)"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>报告</span>
              </template>
              <a-icon-font
                type="iconbaogaobeifen"
                class="icon"
                @click="showRunReport(item.index)"
              />
            </a-tooltip>
            <a-popover
              trigger="hover"
              overlay-class-name="tooltipbox"
              placement="topRight"
              arrow-point-at-center
              :overlay-style="{ fontSize: '12px', width: '100px' }"
            >
              <template slot="content">
                <span class="bangzhu-tooltip">{{ item.description }}</span>
              </template>
              <a-icon-font type="iconbangzhu" class="icon" />
            </a-popover>
          </div>
        </div>
      </div>
    </div>
    <!-- 网络拓扑 header -->
    <div class="data-statistics-header">
      <span>网络-拓扑</span>
      <a-button
        size="small"
        class="run-button"
        @click="runExecuteMetrics('topology')"
        >运行
      </a-button>
      <a-icon
        :type="netTopolygyFoldClose ? 'up' : 'down'"
        @click="netTopolygyFoldClose = !netTopolygyFoldClose"
      />
    </div>
    <!-- 网络拓扑 content -->
    <div
      class="data-analysis-content"
      :class="{ 'close-fold': netTopolygyFoldClose }"
    >
      <div v-for="item in netTop" :key="item.index" class="data-analysis-items">
        <div class="data-analysis-items-title">{{ item.name }}</div>
        <div class="data-analysis-items-info">
          <span>{{ getStatisticValue(item.index) }}</span>
          <div class="hover-icon">
            <!-- 添加 / 取消属性 -->
            <a-tooltip
              v-show="isAvailable(item.index) && item.attributeName"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>{{
                  isHasMetricTag(item.metricTag) ? '取消属性' : '添加为属性'
                }}</span>
              </template>
              <a-icon-font
                :type="
                  isHasMetricTag(item.metricTag)
                    ? 'iconjianshao'
                    : 'iconzengjia'
                "
                class="icon"
                @click="activeAttribute(item)"
              />
            </a-tooltip>
            <!-- 报告 -->
            <a-tooltip
              v-show="item.reportIcon && isAvailable(item.index)"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>报告</span>
              </template>
              <a-icon-font
                type="iconbaogaobeifen"
                class="icon"
                @click="showReport(item.index)"
              />
            </a-tooltip>
            <!-- popover 解释 -->
            <a-popover
              trigger="hover"
              overlay-class-name="tooltipbox"
              placement="topRight"
              arrow-point-at-center
              :overlay-style="{ fontSize: '12px', width: '100px' }"
            >
              <template slot="content">
                <span class="bangzhu-tooltip">{{ item.description }}</span>
              </template>
              <a-icon-font type="iconbangzhu" class="icon" />
            </a-popover>
          </div>
        </div>
      </div>
    </div>
    <!-- 节点计算 header -->
    <div class="data-statistics-header">
      <span>节点计算</span>
      <a-button
        size="small"
        class="run-button"
        @click="runExecuteMetrics('node')"
        >运行
      </a-button>
      <a-icon
        :type="nodeCalFoldClose ? 'up' : 'down'"
        @click="nodeCalFoldClose = !nodeCalFoldClose"
      />
    </div>
    <!-- 节点计算 content -->
    <div
      class="data-analysis-content"
      :class="{ 'close-fold': nodeCalFoldClose }"
    >
      <div
        v-for="item in nodeCal"
        :key="item.index"
        class="data-analysis-items"
      >
        <div class="data-analysis-items-title">{{ item.name }}</div>
        <div class="data-analysis-items-info">
          <span>{{ getStatisticValue(item.index) }}</span>
          <div class="hover-icon">
            <a-tooltip
              v-show="isAvailable(item.index) && item.attributeName"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>{{
                  isHasMetricTag(item.metricTag) ? '取消属性' : '添加为属性'
                }}</span>
              </template>
              <a-icon-font
                :type="
                  isHasMetricTag(item.metricTag)
                    ? 'iconjianshao'
                    : 'iconzengjia'
                "
                class="icon"
                @click="activeAttribute(item)"
              />
            </a-tooltip>

            <a-tooltip
              v-show="item.reportIcon && isAvailable(item.index)"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>报告</span>
              </template>
              <a-icon-font
                type="iconbaogaobeifen"
                class="icon"
                @click="showReport(item.index)"
              />
            </a-tooltip>
            <a-popover
              trigger="hover"
              overlay-class-name="tooltipbox"
              placement="topRight"
              arrow-point-at-center
              :overlay-style="{ fontSize: '12px', width: '100px' }"
            >
              <template slot="content">
                <span class="bangzhu-tooltip">{{ item.description }}</span>
              </template>
              <a-icon-font type="iconbangzhu" class="icon" />
            </a-popover>
          </div>
        </div>
      </div>
    </div>
    <!-- 边计算 header -->
    <div class="data-statistics-header">
      <span>边计算</span>
      <a-button
        size="small"
        class="run-button"
        @click="runExecuteMetrics('link')"
        >运行
      </a-button>
      <a-icon
        :type="edgeCalFoldClose ? 'up' : 'down'"
        @click="edgeCalFoldClose = !edgeCalFoldClose"
      />
    </div>
    <!-- 边计算 content -->
    <div
      class="data-analysis-content"
      :class="{ 'close-fold': edgeCalFoldClose }"
    >
      <div
        v-for="item in edgeCal"
        :key="item.index"
        class="data-analysis-items"
      >
        <div class="data-analysis-items-title">{{ item.name }}</div>
        <div class="data-analysis-items-info">
          <span>{{ getStatisticValue(item.index) }}</span>
          <div class="hover-icon">
            <a-tooltip
              v-show="isAvailable(item.index) && item.attributeName"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>{{
                  isHasMetricTag(item.metricTag) ? '取消属性' : '添加为属性'
                }}</span>
              </template>
              <a-icon-font
                :type="
                  isHasMetricTag(item.metricTag)
                    ? 'iconjianshao'
                    : 'iconzengjia'
                "
                class="icon"
                @click="activeAttribute(item)"
              />
            </a-tooltip>

            <a-tooltip
              v-show="item.reportIcon && isAvailable(item.index)"
              placement="top"
              :overlay-style="{ fontSize: '12px' }"
            >
              <template slot="title">
                <span>报告</span>
              </template>
              <a-icon-font
                type="iconbaogaobeifen"
                class="icon"
                @click="showReport(item.index)"
              />
            </a-tooltip>
            <a-popover
              trigger="hover"
              overlay-class-name="tooltipbox"
              placement="topRight"
              arrow-point-at-center
              :overlay-style="{ fontSize: '12px', width: '100px' }"
            >
              <template slot="content">
                <span class="bangzhu-tooltip">{{ item.description }}</span>
              </template>
              <a-icon-font type="iconbangzhu" class="icon" />
            </a-popover>
          </div>
        </div>
      </div>
    </div>
    <!-- 报告弹窗 -->
    <data-analysis-report
      ref="report"
      :visible="reportShow"
      :report-data="reportData"
      @closeReport="closeReport"
    />
  </div>
</template>

<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import {
  queryMetrics,
  queryPageRank,
  queryCluster,
  activateMetric,
  executeMetrics,
} from '@/api/graph-analysis'
import DataAnalysisReport from '@/components/graph-analysis/right-drawer/data-statistics/DataAnalysisReport.vue'
import GraphAnalysis from '@/store/modules/graphanalysis'
import {
  NetTop,
  NodeCal,
  EdgeCal,
  NetAlgrithm,
} from '@/components/graph-analysis/right-drawer/data-statistics/data-statistics'

// import {debounce} from 'lodash'

@Component({
  components: { DataAnalysisReport },
})
export default class DataStatistics extends Vue {
  private netAlgorithmFoldClose: boolean = false // 网络算法折叠
  private netTopolygyFoldClose: boolean = false // 网络拓扑折叠
  private nodeCalFoldClose: boolean = false // 节点计算折叠
  private edgeCalFoldClose: boolean = false // 边计算折叠

  public reportShow: boolean = false // 报告视图
  public taskId: number = 0

  public reportData: any = {
    AvgDist: {},
    BetweennessCentrality: {},
    ClosenessCentrality: {},
    Cluster: {},
    Density: {},
    Diameter: {},
    Eccentricity: {},
    MeanDegree: {},
    MeanWeightedDegree: {},
    PageRank: {},
    EigenvectorCentrality: {},
    ConnectedComponents: {},
    ClusteringCoefficient: {},
    Triangles: {},
  } // 统计报告结果
  public result: any = 0 // 当前统计报告结果
  public chartData: any = {} // 当前统计报告对应图表数据
  public netTop: any = {} // 网络拓扑信息
  public nodeCal: any = {} // 节点计算信息
  public edgeCal: any = {} // 边计算信息
  public netAlgrithm: any = {} // 网络算法信息

  public mounted() {
    this.queryReportData()
    // 报告信息显示项初始化
    this.netTop = NetTop
    this.nodeCal = NodeCal
    this.edgeCal = EdgeCal
    this.netAlgrithm = NetAlgrithm
  }

  public showReport(index: number) {
    ;(this.$refs.report as DataAnalysisReport).init(index)
    this.reportShow = true
  }

  public closeReport(flag: boolean) {
    this.reportShow = flag
  }

  // 当前graphId
  public get graphId() {
    return GraphAnalysis.activeTabId
  }

  private getStatisticValue(index: number) {
    switch (index) {
      case 1: // 平均度
        return this.reportData.MeanDegree.value
      case 2: // 平均加权度
        return this.reportData.MeanWeightedDegree.value
      case 3: // 图密度
        return this.reportData.Density.value
      case 4: // 连通分量
        return this.reportData.ConnectedComponents.value
      case 5: // 网络直径
        return this.reportData.Diameter.value
      case 6: // 聚类系数
        return this.reportData.ClusteringCoefficient.value
      case 8: // 平均路径长度
        return this.reportData.AvgDist.value
      default:
        // 7-特征向量中心度 9-社团检测 10-PageRank
        return ''
    }
  }

  private isAvailable(index: number) {
    switch (index) {
      case 1: // 平均度
        return this.reportData.MeanDegree.value !== undefined
      case 2: // 平均加权度
        return this.reportData.MeanWeightedDegree.value !== undefined
      case 3: // 图密度
        return this.reportData.Density.value !== undefined
      case 4: // 连通分量
        return this.reportData.ConnectedComponents.value !== undefined
      case 5: // 网络直径
        return this.reportData.Diameter.value !== undefined
      case 6: // 聚类系数
        return this.reportData.ClusteringCoefficient.value !== undefined
      case 7: // 特征向量中心度
        return this.reportData.EigenvectorCentrality.detail !== undefined
      case 8: // 平均路径长度
        return this.reportData.AvgDist.value !== undefined
      case 9: // 社团检测
        return this.reportData.Cluster.detail !== undefined
      case 10: // PageRank
        return this.reportData.PageRank.detail !== undefined
      default:
        return false
    }
  }

  /**
   * 监听 graphId (即 tab 的变化)
   */
  @Watch('graphId')
  public queryReportData() {
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
    }
    queryMetrics({ data }).then((response: any) => {
      if (response.data.code === 100) {
        // 统计报告结果
        this.reportData = this.handleReportData(response.data.result)
      }
    })
  }

  // reportData 后处理
  private handleReportData(responseData: any) {
    const data = responseData

    if (data.ConnectedComponents.WeaklyConnectedComponents) {
      data.ConnectedComponents.value =
        data.ConnectedComponents.WeaklyConnectedComponents.value
    }
    if (data.ConnectedComponents.ConnectedComponents) {
      data.ConnectedComponents.value =
        data.ConnectedComponents.ConnectedComponents.value
    }

    return data
  }

  // 社团检测算法
  public async runCluster() {
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
    }
    await queryCluster({ data }).then((response: any) => {
      if (response.data.code === 100) {
        this.reportData.Cluster = response.data.result
        if (this.reportData.Cluster.detail !== undefined) {
          this.$message.success('运行结束，请点击报告查看')
        }
        this.queryAvailableCategory()
      }
    })
  }

  public showClusterReport() {
    if (this.reportData.Cluster === null) {
      this.$message.warning('请先运行')
    } else {
      this.showReport(9)
    }
  }

  // PageRank算法
  public runPageRank() {
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
    }
    queryPageRank({ data }).then((response: any) => {
      if (response.data.code === 100) {
        this.reportData.PageRank = response.data.result
        if (this.reportData.PageRank.detail !== undefined) {
          this.$message.success('运行结束，请点击报告查看')
        }
        this.queryAvailableCategory()
      }
    })
  }

  public showPageRankReport() {
    if (this.reportData.PageRank === null) {
      this.$message.warning('请先运行')
    } else {
      this.showReport(10)
    }
  }

  public runFunction(index: number) {
    if (index === 9) {
      this.runCluster()
    } else {
      this.runPageRank()
    }
  }

  public showRunReport(index: number) {
    if (index === 9) {
      this.showClusterReport()
    } else {
      this.showPageRankReport()
    }
  }

  private activeAttribute(item: any) {
    const { metricTag, attributeName, index } = item
    const activate = !this.isHasMetricTag(metricTag)
    const message = activate ? '已添加属性' : '已取消属性'
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
      metricTag,
      activate,
    }
    activateMetric({ data }).then((response: any) => {
      if (response.data.code === 100) {
        this.queryAvailableCategory()

        // 连通分量单独判断是否为有向无向
        if (index === 4) {
          const [undirectMessage, ...directedMessage] = attributeName.split(
            '、'
          )
          if (GraphAnalysis.graphDirected) {
            this.$message.success(`${message}:${directedMessage}`)
          } else {
            this.$message.success(`${message}:${undirectMessage}`)
          }
        } else {
          this.$message.success(`${message}:${attributeName}`)
        }
      }
    })
  }

  // 当前指标是否已添加为属性
  private isHasMetricTag(tag: any) {
    let metricTag = ''
    switch (tag) {
      case 'MeanDegree':
        metricTag = 'Degree'
        break
      case 'MeanWeightedDegree':
        metricTag = 'WeightedDegree'
        break
      case 'Diameter':
        metricTag = 'Eccentricity'
        break
      case 'AvgDist':
        metricTag = 'Eccentricity'
        break
      case 'ConnectedComponents':
        return (
          GraphAnalysis.shareAttr.includes('ConnectedID') ||
          GraphAnalysis.shareAttr.includes('StronglyConnectedID')
        )
      default:
        metricTag = tag
    }

    return GraphAnalysis.shareAttr.includes(metricTag)
  }

  // 执行手动查询
  public runExecuteMetrics(runType: any) {
    const data: any = {
      projectId: GraphAnalysis.projectId,
      graphId: GraphAnalysis.activeTabId,
      type: runType,
    }
    executeMetrics({ data }).then((response: any) => {
      if (response.data.code === 100) {
        this.queryReportData()
        this.$message.success('运行完成')
        this.queryAvailableCategory()
      }
    })
  }

  /**
   * 更新图分类节点， 进而更新布局样式里的属性着色和排序设置
   */
  public queryAvailableCategory() {
    GraphAnalysis.queryAvailableCategory()
  }
}
</script>

<style scoped lang="less">
@import '@/styles/common-style';
@import '@/styles/scroll-bar';

.analysis-data-statistics {
  background-color: #f8f7fd;
  height: calc(100% - 37px);
  overflow: hidden;
  overflow-y: auto;
  width: 100%;

  // header
  .data-statistics-header {
    align-items: center;
    background-color: #f9f9fc;
    border-top: 1px solid #e9e9e9;
    color: #5d637e;
    display: flex;
    font-size: 14px;
    font-weight: bold;
    height: 38px;
    justify-content: space-between;
    letter-spacing: 1px;
    padding: 0 24px;
    position: relative;
    user-select: none;

    .run-button {
      height: 24px;
      justify-content: flex-end;
      left: 236px;
      position: absolute;
      width: 57px;

      &:hover {
        background-color: #6973ff;
        color: #fff;
      }
    }
  }

  .data-analysis-content {
    height: auto;
    overflow: hidden;
    width: 100%;

    .data-analysis-items {
      color: #5d637e;
      display: flex;
      font-size: 14px;
      font-weight: 400;
      height: 38px;
      letter-spacing: 1px;
      padding: 8px 18px 8px 36px;

      .data-analysis-items-title {
        color: #5d637e;
        font-size: 14px;
        font-weight: 400;
        letter-spacing: 1px;
        user-select: none;
        width: 200px;
      }

      .data-analysis-items-info {
        align-items: center;
        display: flex;
        justify-content: space-between;
        width: calc(100% - 210px);

        .run-button {
          height: 24px;
          justify-content: flex-end;
          width: 57px;

          &:hover {
            background-color: #6973ff;
            color: #fff;
          }
        }

        .hover-icon {
          color: #5d637e;
          display: flex;
        }

        .icon {
          font-size: 16px;
          margin-left: 8px;
          visibility: hidden;
        }
      }

      &:hover {
        background-color: rgb(233, 236, 253);

        .icon {
          visibility: visible;
        }
      }
    }
  }

  // 折叠
  .close-fold {
    height: 0;
  }

  &::-webkit-scrollbar {
    height: 6px;
    width: 6px;
  }

  &::-webkit-scrollbar-track {
    background: rgb(239, 239, 239);
    border-radius: 2px;
  }

  &::-webkit-scrollbar-thumb {
    background: #bfbfbf;
    border-radius: 6px;
  }

  &::-webkit-scrollbar-thumb:hover {
    background: #888;
  }

  &::-webkit-scrollbar-button {
    background-color: #f1f1f1;
    height: 6px;
    width: 6px;
  }

  &::-webkit-scrollbar-corner {
    background: transparent;
  }
}
</style>

<style lang="less">
.tooltipbox {
  font-size: 14px;
  text-align: middle;

  .ant-popover-inner-content {
    padding: 6px 8px;
  }
}
</style>
